home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1996 October / MACPOWER-1996-10.ISO.7z / MACPOWER-1996-10.ISO / AMUG / Internet_31 / NetCacheResolver 0.9d6 / NetCacheResolver 0.9d6 ト / library / NCR_Resolve.c < prev    next >
Text File  |  1996-05-12  |  14KB  |  433 lines

  1. // NetCache Resolver, 1995-96 (C) Mizutori Tetsuya
  2. // - NCR_Resolve.c, October 8, 1995, May 12 1996
  3. // This document is pretty printed in 10-point Geneva font.
  4.  
  5. #include "NCR_Basic.h"
  6. #include "NCR_Resolve.h"
  7. #include "NCR_File.h"
  8. #include "NCR_Error.h"
  9. #ifdef DEBUG
  10. #include "NCR_Message.h"
  11. #endif /*DEBUG */
  12.  
  13. // definition
  14. // in Header
  15. #define    OFFS_BLOCKSIZE    0x00000C
  16. #define    OFFS_NUMBPAIRS    0x000038
  17.  
  18. // start with pURL
  19. #define    OFFS_URL_STR        4
  20.  
  21. // start with pFInfo
  22. #define    OFFS_CACHE_INFO    4
  23. #define    WIDTH_CACHE_INFO    25    // 5*sizeof(long) + 1 + sizeof(long)
  24. #define    OFFS_DATE1        OFFS_CACHE_INFO + 4
  25. #define    OFFS_DATE2        OFFS_CACHE_INFO + 8
  26. #define    OFFS_FILESIZE        OFFS_CACHE_INFO + 16
  27. #define    OFFS_CACHE_STR    OFFS_CACHE_INFO + WIDTH_CACHE_INFO
  28.  
  29. #define    OFFS_DOC_INFO        OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
  30. //#define    WIDTH_DOC_INFO    29        // October 8, 1995; char[1]+long[7]
  31.     #define    WIDTH_DOC_INFO    17    // May 12, 1996; char[1]+long[4]
  32. #define    OFFS_DOC_COUNT    OFFS_DOC_INFO + WIDTH_DOC_INFO + 4    // +char[1]+long[5]
  33.     #define    OFFS_EXPORT_STR    OFFS_DOC_INFO + WIDTH_DOC_INFO
  34.     #define    OFFS_EXDATA_STR    OFFS_EXPORT_STR + 4/* +#(OFFS_EXPORT_STR) */
  35. // #define    OFFS_FORM_STR    OFFS_DOC_INFO + WIDTH_DOC_INFO    // October 8, 1995
  36. #define    OFFS_FORM_STR    OFFS_DOC_INFO+ 4/* +#(OFFS_EXPORT_STR) */ + 4/* +#(OFFS_EXDATA_STR) */
  37. #define    OFFS_TYPE_STR        OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
  38.  
  39. typedef struct {    // If len is zero, then no allocation space for str[] is occupied.
  40.     unsigned long    len;        // length of string, including the terminator '¥0'
  41.     unsigned char    str[];    // character string, teminated by '¥0'
  42. } QString;        // size of QString is at least 4 bytes, which is the case that len is zero.
  43.  
  44. typedef struct {    // length of DummyData record must be determined dynamically
  45.     unsigned char    dumchar;    // the first filler character
  46.     unsigned char    dumstr[];
  47. } DummyData;
  48.  
  49. typedef struct {
  50.     unsigned long    size;        // total size occupied by this record, in bytes
  51.     QString        url;        // e.g. "http://www.a.b.c/index.html"
  52.     unsigned long    _end;        // ? = 0x0000 (terminator ?)
  53. } _URL_Record;
  54.  
  55.  
  56. typedef struct {
  57.     unsigned long    size;        // total size occupied by this record, in bytes
  58. // OFFS_CACHE_INFO
  59.     unsigned long    _1;        // ? = 0x0003
  60.     unsigned long    date1;    // time stamp 1 (creation ?)
  61.     unsigned long    date2;    // time stamp 2 (modification ?)
  62.     unsigned long    _2;        // ? = 0x0000
  63.     unsigned long    filesize;    // cache file size, in bytes
  64.     unsigned char    _3;        // ? = 0x00, odd byte!
  65.     unsigned long    _4;        // ? = 0x0000 (count-1 for strings followed ?)
  66. // OFFS_CACHE_STR
  67.     QString        cache;    // e.g. "cache123000.html"
  68. // OFFS_DOC_INFO
  69. /***** October 8, 1995 *****
  70.     unsigned long    _5[6];    // ? = {0,1,0,0,0,0}
  71.     unsigned char    _6;        // ? = 0x00, odd byte!
  72.     unsigned long    _7;        // ? = 0x0000 or 0x0001 (count-1 for strings followed ?)
  73. *****/
  74. /***** May 12, 1995 *****/
  75.     unsigned long    _5;        // ? = 0x0000
  76.     unsigned char    _6;        // ? = 0x01, odd byte!
  77.     unsigned long    _51;        // ? = 0x0000 or 0x0002
  78.     unsigned long    _52;        // ? = 0x0000 or 0x0008
  79.     unsigned long    _53;        // ? = 0x0000 or 0x0028
  80.     // OFFS_EXPORT_STR
  81.     QString        export;    // e.g. "RC4-Export"
  82.     // OFFS_EXDATA_STR
  83.     QString        exdata;    // e.g. "???Data Export Inc. v.1.0..."
  84.     unsigned long    _7;        // ? = 0x0000 or 0x0001 (count-1 for strings followed ?)
  85. // OFFS_FORM_STR
  86.     QString        form;    // e.g. "Content-type: application..."
  87. // OFFS_TYPE_STR
  88.     QString        type;        // e.g. "text/html"
  89.     unsigned char    _8[9];    // ? = {all 0x00's}, odd bytes!
  90.     unsigned long    fsize;        // cache file size, in bytes (same value to .filesize)
  91.     DummyData    _9;        // ? = filled by 0x00's, even or odd bytes!
  92.     unsigned long    _end;        // ? = 0x0000 (terminator ?)
  93. } _FInfo_Record;
  94.  
  95.  
  96. typedef struct {
  97.     unsigned long    url;
  98.     unsigned long    cache;
  99.     unsigned long    form;
  100.     unsigned long    type;
  101.     unsigned long    sizeurl;
  102.     unsigned long    sizecache;
  103.     unsigned long    sizeform;
  104.     unsigned long    sizetype;
  105.     unsigned long    filesize;
  106.     unsigned long    date1, date2;
  107. } IndexTableRecord, *IndexTablePtr, **IndexTableHandle;
  108.  
  109. // prototype
  110. static unsigned long GetLongLH (unsigned char *p );
  111.  
  112. static OSErr SetupHeader ( Handle theHndl );
  113. static OSErr DoHandleCacheData ( Handle theHndlData, Handle theHndl );
  114. static OSErr MakeRecord ( Handle theHndl, unsigned long startOffset, long index, IndexTableRecord *table );
  115. static OSErr PrintRecord ( Handle theHndl, long index, IndexTableRecord *table );
  116. static OSErr InsertRecord ( Handle theHndl, Handle theHndl2, long index, IndexTableRecord *table );
  117. static OSErr InsertHeader ( Handle theHndl, Handle theHndl2 );
  118. static OSErr AppendString ( Handle theHndl, const char *str, Size length );
  119.  
  120. /***** General functions *****/
  121.  
  122. #define GetWordHL(p) ( (unsigned short) * ( (unsigned short *) (p) ) )
  123. #define GetLongHL(p) ( (unsigned long) * ( (unsigned long *) (p) ) )
  124.  
  125. static unsigned long GetLongLH (unsigned char *p )
  126. {
  127.     unsigned long    n = 0;
  128.     unsigned char    *q;
  129.     
  130.     q = (unsigned char *) &n;
  131.     
  132.     q[0] = p[3];
  133.     q[1] = p[2];
  134.     q[2] = p[1];
  135.     q[3] = p[0];
  136.     
  137.     return n;
  138. }
  139.  
  140. /***** Read Database from the file *****/
  141. OSErr GetRecordFromFile ( FSSpec *theFSSpec, FInfo *theFInfo, Handle theHndl, long *count )
  142. {
  143.     Handle        theHndlData = nil;
  144.     long            datasize;
  145.     OSType        fdType = 'DBMC';        // read from 'STR#'
  146.     Str31        strFdType;
  147.     OSErr        err = noErr;
  148.     
  149.     // read database from the file
  150.     GetIndString( strFdType, STRID_CACHE, STRIX_CCACHETYPE );
  151.     BlockMove( &strFdType[1], &fdType, 4 );
  152.  
  153.     err = FSpGetFInfo( theFSSpec, theFInfo );
  154.     if ( err != noErr ) { ErrorMessageFS( err, false ); goto out; }
  155.  
  156.     if ( theFInfo->fdType != fdType ) {
  157.         err = errAEWrongDataType;
  158.         ErrorMessageAE( err, false ); goto out; }
  159.  
  160.     theHndlData = NewHandleClear( 0 );            // create a Handle 'theHndlData'
  161.     if ( (err=MemError()) != noErr ) { ErrorMessageMEM( err, true ); }
  162.  
  163.     err = ReadFile( theFSSpec, theFInfo, theHndlData, &datasize );
  164.     if ( err != noErr ) { ErrorMessageFS( err, false ); goto out; }
  165.     
  166.     // convert 'theHndlData' to 'theHndl'
  167.     err = DoHandleCacheData( theHndlData, theHndl );
  168.     *count = GetHandleSize( theHndl );
  169.  
  170.   out:
  171.       if ( theHndlData != nil ) DisposeHandle( theHndlData );    // dispose the Handle 'theHndlData'
  172.       
  173.     return err;
  174. }
  175.  
  176.  
  177. /***** do Handle Data *****/
  178. // globals
  179. unsigned long    gHndlSize = 0;            // set by GetHandleSize()
  180. unsigned long    gBlockSize = 0x004000;    // read from at the offset 'OFFS_BLOCKSIZE'
  181.  
  182. static OSErr SetupHeader ( Handle theHndl )
  183. {
  184.     if ( gHndlSize != 0 ) return noErr;
  185.  
  186.     gHndlSize = GetHandleSize( theHndl );
  187.     gBlockSize = GetLongHL((unsigned char *)*theHndl+OFFS_BLOCKSIZE );
  188.     
  189.     return noErr;
  190. }
  191.  
  192.  
  193. static OSErr DoHandleCacheData ( Handle theHndlData, Handle theHndl )
  194. {
  195.     IndexTableRecord    table;
  196.     unsigned long        n, index;
  197.     unsigned long        startOffset;
  198.     OSErr            err;
  199.  
  200. #ifdef DEBUG
  201.     Message("DoHandleData() start¥n");
  202. #endif /* DEBUG */
  203.  
  204.     SetupHeader( theHndlData );
  205.     
  206.     InsertHeader( theHndlData, theHndl );
  207.     
  208.     n = 0;
  209.     startOffset = gBlockSize;
  210.     while ( startOffset < gHndlSize ) {
  211.         for ( index=1; ; index++) {
  212.             err = MakeRecord( theHndlData, startOffset, index, &table );
  213.             if ( err == nilHandleErr ) break;
  214.             if ( err != noErr ) continue;
  215. //            PrintRecord( theHndlData, n, &table );
  216.             InsertRecord( theHndlData, theHndl, n, &table );
  217.             n++;
  218.         }
  219.         startOffset += gBlockSize;
  220.     }
  221.     
  222. #ifdef DEBUG
  223.     Message("DoHandleData() end¥n");
  224. #endif /* DEBUG */
  225.     return noErr;
  226. }
  227.  
  228. /***** Make Record *****/
  229. #define ALLOWANCE_TOC        4096
  230. #define ALLOWANCE_LENGH        255
  231.  
  232. // index should begin with 1, not 0
  233. static OSErr MakeRecord ( Handle theHndl, unsigned long startOffset, long index, IndexTableRecord *table )
  234. {
  235.     long            count;
  236.     long            offsetURL, offsetFInfo;
  237.     unsigned char    *pHeap, *pHashTable, *pURL, *pFInfo;
  238.     long            sizeURL, sizeCache, sizeForm, sizeType;
  239.     unsigned char    *strURL, *strCache, *strForm, *strType;
  240.     unsigned long    filesize, date1, date2;
  241.     unsigned long    exportsize, exdatasize;
  242.     OSErr        err = noErr;
  243.     
  244.     HLock( theHndl );
  245.     
  246.     pHeap = (unsigned char *) *theHndl;
  247.     pHashTable = (unsigned char *) *theHndl + startOffset;
  248.     count = GetWordHL(pHashTable);
  249.     if ( count <= 0 || ALLOWANCE_TOC <= count ) { err = nilHandleErr; goto out; }
  250.     
  251.     count /= 2;
  252.     if ( index < 1 || count < index ) { err = nilHandleErr; goto out; }
  253.     index -= 1;
  254.     
  255.     // for URL
  256. //    offsetURL = GetWordHL( pHashTable + 4*index+2 );
  257.     pURL = pHashTable + GetWordHL( pHashTable + 4*index+2 );
  258.     
  259. //#define    OFFS_URL_STR        4
  260.     offsetURL = OFFS_URL_STR;
  261.     sizeURL = GetLongLH(pURL+offsetURL);
  262.     strURL = (unsigned char *) (pURL+offsetURL+sizeof(long));
  263.     if ( sizeURL <= 0 || ALLOWANCE_LENGH < sizeURL ) { err = paramErr; goto out; }
  264.     offsetURL += sizeof(long) + sizeURL;
  265.  
  266.  
  267.     // for File Info
  268.     pFInfo = pHashTable + GetWordHL( pHashTable + 4*index+4 );
  269. //#define    OFFS_CACHE_INFO    4
  270. //#define    WIDTH_CACHE_INFO    25
  271. //#define    OFFS_CACHE_STR    OFFS_CACHE_INFO + WIDTH_CACHE_INFO
  272.     offsetFInfo = OFFS_CACHE_STR;
  273.     
  274.     // cache filename
  275.     sizeCache = GetLongLH(pFInfo+offsetFInfo);
  276.     strCache = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
  277.     if ( sizeCache <= 0 || ALLOWANCE_LENGH < sizeCache )  { err = paramErr; goto out; }
  278.     offsetFInfo += sizeof(long) + sizeCache;
  279.  
  280. #ifdef COMMENT // October 8, 1995
  281. //#define    OFFS_DOC_INFO        OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
  282. //#define    WIDTH_DOC_INFO    29    // char[1]+long[7]
  283. //#define    OFFS_FORM_STR    OFFS_DOC_INFO + WIDTH_DOC_INFO
  284. //#define    OFFS_TYPE_STR        OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
  285.     offsetFInfo += WIDTH_DOC_INFO;
  286. #endif // COMMENT
  287.  
  288. // May 12, 1996
  289. //#define    OFFS_DOC_INFO        OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
  290. //#define    WIDTH_DOC_INFO    17    // char[1]+long[4]
  291. //#define    OFFS_DOC_COUNT    OFFS_DOC_INFO + WIDTH_DOC_INFO + 4    // +char[1]+long[5]
  292. //#define    OFFS_EXPORT_STR    OFFS_DOC_INFO + WIDTH_DOC_INFO
  293. //#define    OFFS_EXDATA_STR    OFFS_EXPORT_STR + 4/* +#(OFFS_EXPORT_STR) */
  294. //#define    OFFS_FORM_STR    OFFS_DOC_INFO+ 4/* +#(OFFS_EXPORT_STR) */ + 4/* +#(OFFS_EXDATA_STR) */
  295. //#define    OFFS_TYPE_STR        OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
  296.     offsetFInfo += WIDTH_DOC_INFO;
  297.     exportsize = GetLongLH( pFInfo+offsetFInfo );
  298.     offsetFInfo += sizeof(long) + exportsize;
  299.     exdatasize = GetLongLH( pFInfo+offsetFInfo );
  300.     offsetFInfo += sizeof(long) + exdatasize;
  301.     offsetFInfo += sizeof(long);
  302.  
  303.     // content-type (Can be Null string!)
  304.     sizeForm = GetLongLH( pFInfo+offsetFInfo );    
  305.     strForm = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
  306.     if ( sizeForm < 0 || ALLOWANCE_LENGH < sizeForm )  { err = paramErr; goto out; }
  307.     offsetFInfo += sizeof(long) + sizeForm;
  308.  
  309.     // type (Can be Null string!)
  310.     sizeType = GetLongLH( pFInfo+offsetFInfo );    
  311.     strType = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
  312.     if ( sizeType < 0 || ALLOWANCE_LENGH < sizeType )  { err = paramErr; goto out; }
  313.     offsetFInfo += sizeof(long) + sizeType;
  314.     
  315.     table->url = (unsigned long) strURL - (unsigned long) pHeap;
  316.     table->cache = (unsigned long) strCache - (unsigned long) pHeap;
  317.     table->form = (unsigned long) strForm - (unsigned long) pHeap;
  318.     table->type = (unsigned long) strType - (unsigned long) pHeap;
  319.     table->sizeurl = ( sizeURL < 1 ? 0 : sizeURL - 1 ) ;    // truncate the terminator '¥0'
  320.     table->sizecache = ( sizeCache < 1 ? 0 : sizeCache - 1 );
  321.     table->sizeform = ( sizeForm < 1 ? 0 : sizeForm - 1 );
  322.     table->sizetype = ( sizeType < 1 ? 0 : sizeType - 1 );
  323.     table->date1 = GetLongLH( pFInfo+OFFS_DATE1 );
  324.     table->date2 = GetLongLH( pFInfo+OFFS_DATE2 );
  325.     table->filesize = GetLongLH( pFInfo+OFFS_FILESIZE );
  326. //#define    OFFS_DATE1        OFFS_CACHE_INFO + 4
  327. //#define    OFFS_DATE2        OFFS_CACHE_INFO + 8
  328. //#define    OFFS_FILESIZE        OFFS_CACHE_INFO + 16
  329.  
  330.   out:
  331.     HUnlock( theHndl );
  332.     return err;
  333. }
  334.  
  335.  
  336. static OSErr PrintRecord ( Handle theHndl, long index, IndexTableRecord *table )
  337. {
  338.     unsigned char    *pHeap;
  339.     
  340.     HLock( theHndl );
  341.     pHeap = (unsigned char *) *theHndl;
  342.  
  343. #ifdef DEBUG
  344.     Message("[%ld] cache=$%04X url=$%04X type=$%04X size=%ld¥n",
  345.         index, (short) table->cache,  (short) table->url, (short) table->type, table->filesize);
  346.     Message("Cache:%ld('%s')  ", table->sizecache, pHeap+table->cache);
  347.     Message("Type:%ld('%s')¥n", table->sizetype, pHeap+table->type);
  348.     Message("URL:%ld('%s')¥n", table->sizeurl, pHeap+table->url);
  349. #endif /* DEBUG */
  350.  
  351.     HUnlock( theHndl );
  352.     
  353.     return noErr;
  354. }
  355.  
  356.  
  357. #define TAB    "¥t"
  358. #define EOL    "¥r"
  359.  
  360. static OSErr InsertRecord ( Handle theHndl, Handle theHndl2, long index, IndexTableRecord *table )
  361. {
  362.     unsigned char    *pHeap;
  363.     Str255        text;
  364.  
  365.     HLock( theHndl );
  366.     pHeap = (unsigned char *) *theHndl;
  367.     
  368.     // for item 1 (some code '0')
  369.         AppendString( theHndl2, "0" TAB, 2 );
  370.     // for item 2 (date1)
  371.         NumToString(table->date1, text);
  372.         AppendString( theHndl2, (char *) &text[1], text[0] );
  373.         AppendString( theHndl2, TAB, 1 );
  374.     // for item 3 (date2)
  375.         NumToString(table->date2, text);
  376.         AppendString( theHndl2, (char *) &text[1], text[0] );
  377.         AppendString( theHndl2, TAB, 1 );
  378.     // for  item 4 ("cache12300")
  379.         AppendString( theHndl2, (char *) pHeap+table->cache, table->sizecache );
  380.         AppendString( theHndl2, TAB, 1 );
  381.     // for item 5 ("URL")
  382.         AppendString( theHndl2, (char *) pHeap+table->url, table->sizeurl );
  383.         AppendString( theHndl2, TAB, 1 );
  384.     // for item 6 (file/type)
  385.         AppendString( theHndl2, (char *) pHeap+table->type, table->sizetype );
  386.         AppendString( theHndl2, TAB, 1 );
  387.     // for item 7 (format ?)
  388.     //    AppendString( theHndl2, (char *) pHeap+table->form, table->sizeform );
  389.         AppendString( theHndl2, TAB, 1 );
  390.     // for item 8 (file size)
  391.         NumToString(table->filesize, text);
  392.         AppendString( theHndl2, (char *) &text[1], text[0] );
  393.     // for item 9 thru 10 (empty items)
  394.         AppendString( theHndl2, TAB TAB, 2 );
  395.     // for CR
  396.         AppendString( theHndl2, EOL, 1 );
  397.         
  398.     HUnlock( theHndl );
  399.  
  400.     return noErr;
  401. }
  402.  
  403. static OSErr InsertHeader ( Handle theHndl, Handle theHndl2 )
  404. {
  405.     Str255        text;
  406.  
  407.     // for header line
  408.         GetIndString( text, STRID_CACHE, STRIX_FORMAT );
  409.         AppendString( theHndl2, (char *) &text[1], text[0] );
  410.     // for CR
  411.         AppendString( theHndl2, EOL, 1 );
  412.         
  413.     return noErr;
  414. }
  415.  
  416. static OSErr AppendString ( Handle theHndl, const char *str, Size length )
  417. {
  418.     unsigned long    n;
  419.     OSErr        err;
  420.     
  421.     n = GetHandleSize( theHndl );
  422.     
  423.     SetHandleSize( theHndl, n+length );
  424.     if ( (err=MemError()) != noErr )
  425.         ErrorMessageMEM( err, true );
  426.  
  427.     BlockMove( str, (unsigned char *) *theHndl + n, length );
  428.  
  429.     return err;
  430. }
  431.  
  432. // end of program
  433.